package core;

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.LinkedList;

import core.Room.Type;

public class DLV {
	public Floor floor;
	public AbstractAgent agent;

	public DLV(AbstractAgent agent, Floor floor) {
		this.floor = floor;
		this.agent = agent;
	}

	public void writeInitialPlan(int numPassi, String obiettivo, int maxPassi) {
		if(numPassi - 1 > maxPassi && maxPassi > -1)
			return;
		try {
			FileOutputStream file = new FileOutputStream("pianificazione" + obiettivo.toUpperCase() + ".initial.plan");
			PrintStream output = new PrintStream(file);
			output.print("initially: ");
			// Posizione di ciccio
			output.print("onciccio(" + this.floor.rooms[this.agent.x].type + ", " + this.agent.y + "). ");
			for (int i = 0; i < this.floor.rooms.length; i++) {
				for (int j = 0; j < this.floor.rooms[i].squares.length; j++) {
					if (this.floor.rooms[i].squares[j].type != core.Square.Type.clean && this.floor.rooms[i].squares[j].type != core.Square.Type.unknown)
						output.print("on" + this.floor.rooms[i].squares[j].type + "(" + this.floor.rooms[i].type + "," + j + "). ");
				}
			}
			output.println();
			output.print("goal: subgoalreached ? (" + (numPassi - 1) + ")");
			
			output.close();
			file.close();
		} catch (IOException e) {
			System.out.println("Errore: " + e);
		}
	}

	public void writeDl() {
		try {
			FileOutputStream file = new FileOutputStream("pianificazione.dl");
			PrintStream output = new PrintStream(file);
			output.println("#maxint=1000.");

			for (int i = 0; i < 8; i++)
				output.println("cell(" + i + ").");

			for (int i = 0; i < this.floor.rooms.length; i++) {
				output.println("room(" + this.floor.rooms[i].type + "," + i + ").");
			}

			for (int j = 0; j < this.floor.rooms.length; j++) {
				if (j + 1 < this.floor.rooms.length)
					output.println("porta(" + this.floor.rooms[j].type + ","
							+ this.floor.rooms[j + 1].type + "," + this.floor.doors[j].col + ").");
				else
					output.println("porta(" + this.floor.rooms[j].type + ","
							+ Type.entrance + "," + this.floor.doors[j].col + ").");
			}
			output.println("porta(STANZA1, STANZA2, CELLA) :- porta(STANZA2, STANZA1, CELLA).");

			output.println("stanzeAdiacenti(STANZA1, STANZA2) :- room(STANZA1, RIGA1), room(STANZA2, RIGA2), RIGA1 = RIGA2 + 1.");
			output.println("stanzeAdiacenti(STANZA1, STANZA2) :- stanzeAdiacenti(STANZA2, STANZA1).");
			output.println("celleAdiacenti(POSIZIONE1, POSIZIONE2) :- cell(POSIZIONE1), cell(POSIZIONE2), POSIZIONE1 = POSIZIONE2 + 1.");
			output.println("celleAdiacenti(CELLA1, CELLA2) :- celleAdiacenti(CELLA2, CELLA1).");

			output.close();
			file.close();
		} catch (IOException e) {
			System.out.println("Errore: " + e);
		}
	}	

	public String exec(String obiettivo, int maxPassi) {
		int numPassi = 1;
		String comando = "";
		String returned = null;
		boolean stop = false;
		while (!stop) {
			try {
				Runtime r = Runtime.getRuntime();
				comando = "./dlv.exe pianificazione" + obiettivo.toUpperCase() + ".plan pianificazione.dl pianificazione" + obiettivo.toUpperCase() + ".initial.plan -FP -silent";
				Process p = r.exec(comando);
				BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
				String s = bufferedReader.readLine();
				if (s == null) {
					numPassi++;
					if(numPassi - 1 > maxPassi && maxPassi > -1)
						return null;
					writeInitialPlan(numPassi, obiettivo, maxPassi);
				}
				else {
					stop = true;
					returned = "";
				}

				while (s != null) {
					returned += s + "\n";
					s = bufferedReader.readLine();
					if(s.isEmpty())
						s = null;
				}
				
				bufferedReader.close();
				p.destroy();
			} catch (Exception e) {
				System.out.println("ERRORE NELL'ESECUZIONE DEL COMANDO: " + comando);
			}
		}
		return returned;
	}
	
	public LinkedList<String> getPlan(String command) {
		if(command == null)
			return null;
		String[] lines = command.split("\n");
		for (String line : lines) {
			if(line.startsWith("PLAN:")) {
				String[] actions = line.substring(6).split(";");
				LinkedList<String> toReturn = new LinkedList<String>();
				for (String action : actions) {
					if(!action.trim().equals("(no action)")) {
						toReturn.add(action.trim());
						System.err.println(action.trim());
					}
				}
				return toReturn;
			}
		}
		return null;
	}
}